package views
{
	import Events.*;
	
	import com.oosterwijk.irc.FlexIrcClient;
	import com.oosterwijk.irc.User;
	import com.oosterwijk.irc.event.*;
	
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.text.StyleSheet;
	import flash.text.TextFieldAutoSize;
	import flash.ui.Keyboard;
	import flash.utils.*;
	
	import flashx.textLayout.elements.ListElement;
	
	import org.osmf.net.StreamingURLResource;
	
	import qnx.ui.buttons.*;
	import qnx.ui.core.*;
	import qnx.ui.data.DataProvider;
	import qnx.ui.events.ListEvent;
	import qnx.ui.events.ScrollEvent;
	import qnx.ui.listClasses.DropDown;
	import qnx.ui.listClasses.List;
	import qnx.ui.listClasses.ListSelectionMode;
	import qnx.ui.listClasses.ScrollDirection;
	import qnx.ui.listClasses.ScrollPane;
	import qnx.ui.text.Label;
	import qnx.ui.text.TextInput;

	public class ChannelView extends BaseView implements IRCView
	{
		private var _txtScrlr:ScrollPane;
		private var _statusText:Label;
		private var _userList:List;
		private var _sendBT:LabelButton;
		private var _inputTI:TextInput;
		private var _targetLbl:Label;
		private var _actionDP:DropDown;
		private var _actionArr:Array;
		/* the Flex IRC Client Object */
		private var _flexIrcClient:FlexIrcClient = null;
		/* the name of the channel this window represents */
		private var _channel:String = null;
		public function ChannelView(flexIrcClient:FlexIrcClient, channel:String)
		{
			super();
			_channel = channel;
			_flexIrcClient = flexIrcClient;
			configUI();
			this.appendHTML("<span class='channelMsg'>* Now talking in " + channel + "</span><br>");
		}
		
		private function configUI():void
		{
			var mainContainer:Container = new Container();
			//mainContainer.margins = Vector.<Number>([2,2,2,2]);
			mainContainer.flow = ContainerFlow.HORIZONTAL;
			//mainContainer.debugColor = 0xFFCC00;
			this.addChild(mainContainer);
			
			// create subcontainer on left side of the screen 
			var mySub:Container = new Container();
			//mySub.margins = Vector.<Number>([2,2,2,2]);            
			mySub.flow = ContainerFlow.VERTICAL;
			//mySub.debugColor = 0xFF3300;
			mySub.padding = 10;
			mySub.size = 80;
			mySub.sizeUnit = SizeUnit.PERCENT;
			mySub.align = ContainerAlign.NEAR;
			
			_txtScrlr = new ScrollPane();
			//scrlr.setPosition(0, 0);
			_txtScrlr.size = 100;

			_txtScrlr.sizeUnit = SizeUnit.PERCENT;
			_txtScrlr.scrollDirection = ScrollDirection.VERTICAL;
			
			var css:StyleSheet = new StyleSheet();
			css.setStyle("body", {fontFamily:'Courier New', fontSize:'18'});
			css.setStyle(".channelMsg", {color:'#348017'});
			css.setStyle(".serverMsg", {color:'#2554C7'});
			css.setStyle(".msg2me", {fontWeight:'bold', backgroundColor:'#E0FFFF'});
			
			_statusText = new Label();
			_statusText.autoSize = TextFieldAutoSize.LEFT;
			_statusText.multiline = true;
			_statusText.textField.wordWrap = true;
			_statusText.width = 816;
			_statusText.textField.styleSheet = css;
			_statusText.htmlText = "<body>";
			//statusText.height = 470;
			_txtScrlr.setScrollContent(_statusText);
			
			mySub.addChild(_txtScrlr);
			
			// userlist
			var mySubRight:Container = new Container();
			mySubRight.margins = Vector.<Number>([1,1,1,1]);            
			mySubRight.flow = ContainerFlow.VERTICAL;
			mySubRight.debugColor = 0xC0C0C0;
			mySubRight.padding = 10;
			mySubRight.size = 20;
			mySubRight.sizeUnit = SizeUnit.PERCENT;			
			mySubRight.align = ContainerAlign.MID;
			
			_userList = new List();                       
			_userList.size = 100;
			_userList.sizeUnit = SizeUnit.PERCENT;
			_userList.columnWidth = 350;
			_userList.setSkin(UserListRenderer);
			
			//set the dataProvider
			_userList.allowDeselect = false;
			_userList.selectionMode = ListSelectionMode.SINGLE;
			_userList.scrollDirection = ScrollDirection.VERTICAL;
			//_chList.dataProvider = new DataProvider(_chArray);
			_userList.addEventListener(ListEvent.ITEM_CLICKED, onUserListClick);
			mySubRight.addChild(_userList);
			
			
			// create subcontainer as the bottom frame //
			var bottomContainer:Container = new Container();
			bottomContainer.margins = Vector.<Number>([5,5,5,5]);            
			//bottomContainer.debugColor = 0x33FF33;
			bottomContainer.size = 10;
			bottomContainer.sizeUnit = SizeUnit.PERCENT;
			bottomContainer.flow = ContainerFlow.HORIZONTAL;
			bottomContainer.align = ContainerAlign.FAR;
			bottomContainer.containment = Containment.DOCK_BOTTOM; 
			// input and send //
			_targetLbl = new Label();
			_targetLbl.width = 120;
			_targetLbl.text = "Target";
			_targetLbl.addEventListener(MouseEvent.CLICK, onTargetLblClick);
			
			_actionArr = [];
			_actionArr.push({label:"Private"});
			_actionArr.push({label:"Kick"});
			_actionDP = new DropDown();
			_actionDP.dataProvider = new DataProvider(_actionArr);
			_actionDP.enabled = false;
			_actionDP.showListAbove = true;
			//_actionDP.width = 180;
			_actionDP.addEventListener(Event.SELECT, onUserAction);
			
			_sendBT = new LabelButton();
			_sendBT.label = "Send";
			_sendBT.size = 90;
			_sendBT.addEventListener(MouseEvent.CLICK, onSend);
 			
			_inputTI = new TextInput();
			_inputTI.width = 600;
			_inputTI.height = 40;
			_inputTI.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
			
			bottomContainer.addChild(_targetLbl);
			bottomContainer.addChild(_actionDP);
			bottomContainer.addChild(_inputTI); 
			bottomContainer.addChild(_sendBT);
			
			
			mainContainer.addChild(mySub);
			mainContainer.addChild(mySubRight);
			mainContainer.addChild(bottomContainer);
			
			mainContainer.setSize(1024, 540);
		}
		
		/**
		 * This function will register itself for the following events on the 
		 * FlexIrcClient. 
		 *
		 * INVITE_EVENT, USER_LIST_EVENT, MESSAGE_EVENT
		 * JOIN_EVENT, PART_EVENT, KICK_EVENT
		 * TOPIC_EVENT, CHANNEL_INFO_EVENT, MODE_EVENT
		 * OP_EVENT, DE_OP_EVENT, VOICE_EVENT
		 * DE_VOICE_EVENT, SET_CHANNEL_KEY_EVENT, REMOVE_CHANNEL_KEY_EVENT
		 * SET_CHANNEL_LIMIT_EVENT, REMOVE_CHANNEL_LIMIT_EVENT, SET_CHANNEL_BAN_EVENT
		 * REMOVE_CHANNEL_BAN_EVENT, SET_TOPIC_PROTECTION_EVENT, REMOVE_TOPIC_PROTECTION_EVENT
		 * SET_NO_EXTERNAL_MESSAGES_EVENT, REMOVE_NO_EXTERNAL_MESSAGES_EVENT, SET_INVITE_ONLY_EVENT
		 * REMOVE_INVITE_ONLY_EVENT, SET_MODERATED_EVENT, REMOVE_MODERATED_EVENT
		 * SET_PRIVATE_EVENT, REMOVE_PRIVATE_EVENT, SET_SECRET_EVENT
		 * REMOVE_SECRECT_EVENT
		 *
		 */
		public function registerListeners(flexIrcClient:FlexIrcClient):void
		{
			flexIrcClient.addEventListener(FlexIrcClient.INVITE_EVENT,onInvite);
			flexIrcClient.addEventListener(FlexIrcClient.USER_LIST_EVENT,onUserList);
			flexIrcClient.addEventListener(FlexIrcClient.MESSAGE_EVENT,onMessage);
			flexIrcClient.addEventListener(FlexIrcClient.JOIN_EVENT,onJoin);
			flexIrcClient.addEventListener(FlexIrcClient.PART_EVENT,onPart);
			flexIrcClient.addEventListener(FlexIrcClient.QUIT_EVENT,onQuit);
			flexIrcClient.addEventListener(FlexIrcClient.KICK_EVENT,onKick);
			flexIrcClient.addEventListener(FlexIrcClient.TOPIC_EVENT,onTopic);
			flexIrcClient.addEventListener(FlexIrcClient.CHANNEL_INFO_EVENT,onChannelInfo);
			flexIrcClient.addEventListener(FlexIrcClient.OP_EVENT,onOp);
			flexIrcClient.addEventListener(FlexIrcClient.DE_OP_EVENT,onDeop);
			flexIrcClient.addEventListener(FlexIrcClient.VOICE_EVENT,onVoice);
			flexIrcClient.addEventListener(FlexIrcClient.DE_VOICE_EVENT,onDeVoice);
			flexIrcClient.addEventListener(FlexIrcClient.SET_CHANNEL_KEY_EVENT,onSetChannelKey);
			flexIrcClient.addEventListener(FlexIrcClient.REMOVE_CHANNEL_KEY_EVENT,onRemoveChannelKey);
			flexIrcClient.addEventListener(FlexIrcClient.SET_CHANNEL_LIMIT_EVENT,onSetChannelLimit);
			flexIrcClient.addEventListener(FlexIrcClient.REMOVE_CHANNEL_LIMIT_EVENT,onRemoveChannelLimit);
			flexIrcClient.addEventListener(FlexIrcClient.SET_CHANNEL_BAN_EVENT,onSetChannelBan);
			flexIrcClient.addEventListener(FlexIrcClient.REMOVE_CHANNEL_BAN_EVENT,onRemoveChannelBan);
			flexIrcClient.addEventListener(FlexIrcClient.SET_TOPIC_PROTECTION_EVENT,onSetTopicProtection);
			flexIrcClient.addEventListener(FlexIrcClient.REMOVE_TOPIC_PROTECTION_EVENT,onRemoveTopicProtection);
			flexIrcClient.addEventListener(FlexIrcClient.SET_NO_EXTERNAL_MESSAGES_EVENT,onSetNoExternalMessages);
			flexIrcClient.addEventListener(FlexIrcClient.REMOVE_NO_EXTERNAL_MESSAGES_EVENT,onRemoveNoExternalMessages);
			flexIrcClient.addEventListener(FlexIrcClient.SET_INVITE_ONLY_EVENT,onSetInviteOnly);
			flexIrcClient.addEventListener(FlexIrcClient.REMOVE_INVITE_ONLY_EVENT,onRemoveInviteOnly);
			flexIrcClient.addEventListener(FlexIrcClient.SET_MODERATED_EVENT,onSetModerated);
			flexIrcClient.addEventListener(FlexIrcClient.REMOVE_MODERATED_EVENT,onRemoveModerated);
			flexIrcClient.addEventListener(FlexIrcClient.SET_PRIVATE_EVENT,onSetPrivate);
			flexIrcClient.addEventListener(FlexIrcClient.REMOVE_PRIVATE_EVENT,onRemovePrivate);
			flexIrcClient.addEventListener(FlexIrcClient.SET_SECRET_EVENT,onSetSecret);
			flexIrcClient.addEventListener(FlexIrcClient.REMOVE_SECRECT_EVENT,onRemoveSecret);
			flexIrcClient.addEventListener(FlexIrcClient.NICK_CHANGE_EVENT, onNickChange);
			
			flexIrcClient.addEventListener(FlexIrcClient.DISCONNECT_EVENT, onDisconnect);
			flexIrcClient.addEventListener(FlexIrcClient.CONNECT_EVENT, onConnect);
			// Use this if you want access to all mode events. Most of these 
			// are implemented in their own methods 
			//flexIrcClient.addEventListener(FlexIrcClient.MODE_EVENT,onMode);
			
			// These are the listeners for the gui-driven events we respond to
			/*
			addEventListener(ChannelGuiEvent.KICK_USER_EVENT,kickUser);
			addEventListener(ChannelGuiEvent.BAN_USER_EVENT,banUser);
			addEventListener(ChannelGuiEvent.KICK_AND_BAN_USER_EVENT,kickAndBanUser);
			addEventListener(ChannelGuiEvent.OP_USER_EVENT,opUser);
			addEventListener(ChannelGuiEvent.DE_OP_USER_EVENT,deOpUser);
			addEventListener(ChannelGuiEvent.VOICE_USER_EVENT,voiceUser);
			addEventListener(ChannelGuiEvent.DE_VOICE_USER_EVENT,deVoiceUser);
			*/
			
		}
		public function cleanup(flexIrcClient:FlexIrcClient):void
		{
			flexIrcClient.removeEventListener(FlexIrcClient.INVITE_EVENT,onInvite);
			flexIrcClient.removeEventListener(FlexIrcClient.USER_LIST_EVENT,onUserList);
			flexIrcClient.removeEventListener(FlexIrcClient.MESSAGE_EVENT,onMessage);
			flexIrcClient.removeEventListener(FlexIrcClient.JOIN_EVENT,onJoin);
			flexIrcClient.removeEventListener(FlexIrcClient.PART_EVENT,onPart);
			flexIrcClient.removeEventListener(FlexIrcClient.QUIT_EVENT,onQuit);
			flexIrcClient.removeEventListener(FlexIrcClient.KICK_EVENT,onKick);
			flexIrcClient.removeEventListener(FlexIrcClient.TOPIC_EVENT,onTopic);
			flexIrcClient.removeEventListener(FlexIrcClient.CHANNEL_INFO_EVENT,onChannelInfo);
			flexIrcClient.removeEventListener(FlexIrcClient.OP_EVENT,onOp);
			flexIrcClient.removeEventListener(FlexIrcClient.DE_OP_EVENT,onDeop);
			flexIrcClient.removeEventListener(FlexIrcClient.VOICE_EVENT,onVoice);
			flexIrcClient.removeEventListener(FlexIrcClient.DE_VOICE_EVENT,onDeVoice);
			flexIrcClient.removeEventListener(FlexIrcClient.SET_CHANNEL_KEY_EVENT,onSetChannelKey);
			flexIrcClient.removeEventListener(FlexIrcClient.REMOVE_CHANNEL_KEY_EVENT,onRemoveChannelKey);
			flexIrcClient.removeEventListener(FlexIrcClient.SET_CHANNEL_LIMIT_EVENT,onSetChannelLimit);
			flexIrcClient.removeEventListener(FlexIrcClient.REMOVE_CHANNEL_LIMIT_EVENT,onRemoveChannelLimit);
			flexIrcClient.removeEventListener(FlexIrcClient.SET_CHANNEL_BAN_EVENT,onSetChannelBan);
			flexIrcClient.removeEventListener(FlexIrcClient.REMOVE_CHANNEL_BAN_EVENT,onRemoveChannelBan);
			flexIrcClient.removeEventListener(FlexIrcClient.SET_TOPIC_PROTECTION_EVENT,onSetTopicProtection);
			flexIrcClient.removeEventListener(FlexIrcClient.REMOVE_TOPIC_PROTECTION_EVENT,onRemoveTopicProtection);
			flexIrcClient.removeEventListener(FlexIrcClient.SET_NO_EXTERNAL_MESSAGES_EVENT,onSetNoExternalMessages);
			flexIrcClient.removeEventListener(FlexIrcClient.REMOVE_NO_EXTERNAL_MESSAGES_EVENT,onRemoveNoExternalMessages);
			flexIrcClient.removeEventListener(FlexIrcClient.SET_INVITE_ONLY_EVENT,onSetInviteOnly);
			flexIrcClient.removeEventListener(FlexIrcClient.REMOVE_INVITE_ONLY_EVENT,onRemoveInviteOnly);
			flexIrcClient.removeEventListener(FlexIrcClient.SET_MODERATED_EVENT,onSetModerated);
			flexIrcClient.removeEventListener(FlexIrcClient.REMOVE_MODERATED_EVENT,onRemoveModerated);
			flexIrcClient.removeEventListener(FlexIrcClient.SET_PRIVATE_EVENT,onSetPrivate);
			flexIrcClient.removeEventListener(FlexIrcClient.REMOVE_PRIVATE_EVENT,onRemovePrivate);
			flexIrcClient.removeEventListener(FlexIrcClient.SET_SECRET_EVENT,onSetSecret);
			flexIrcClient.removeEventListener(FlexIrcClient.REMOVE_SECRECT_EVENT,onRemoveSecret);
			flexIrcClient.removeEventListener(FlexIrcClient.NICK_CHANGE_EVENT, onNickChange);
			
			flexIrcClient.removeEventListener(FlexIrcClient.DISCONNECT_EVENT, onDisconnect);
			flexIrcClient.removeEventListener(FlexIrcClient.CONNECT_EVENT, onConnect);
			// Use this if you want access to all mode events. Most of these 
			// are implemented in their own methods 
			//flexIrcClient.addEventListener(FlexIrcClient.MODE_EVENT,onMode);
			
			// These are the listeners for the gui-driven events we respond to
			/*
			addEventListener(ChannelGuiEvent.KICK_USER_EVENT,kickUser);
			addEventListener(ChannelGuiEvent.BAN_USER_EVENT,banUser);
			addEventListener(ChannelGuiEvent.KICK_AND_BAN_USER_EVENT,kickAndBanUser);
			addEventListener(ChannelGuiEvent.OP_USER_EVENT,opUser);
			addEventListener(ChannelGuiEvent.DE_OP_USER_EVENT,deOpUser);
			addEventListener(ChannelGuiEvent.VOICE_USER_EVENT,voiceUser);
			addEventListener(ChannelGuiEvent.DE_VOICE_USER_EVENT,deVoiceUser);
			*/
			
			_userList.removeEventListener(ListEvent.ITEM_CLICKED, onUserListClick);
			_inputTI.removeEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
			_sendBT.removeEventListener(MouseEvent.CLICK, onSend);
		}
		private function channelCheck(argChannel:String):Boolean
		{
			return this.channel == argChannel;
		}
		
		private function addNewUserToGui(nick:String):void
		{
			this._userList.dataProvider.addItem(new User('', nick));
			//this.sortUserList();
		}
		
		private function removeUserFromGui(nick:String):Boolean
		{
			var i:int = getUserIndex(nick);
			if(i != -1){
				_userList.dataProvider.removeItemAt(i);
				_userList.invalidate();
				return true;
			}
			return false;
		}
		
		private function renameUserFromGui(nick:String, newNick:String):Boolean
		{
			var i:int = getUserIndex(nick);
			if(i != -1){
				var user:User = _userList.dataProvider.getItemAt(i) as User;
				user.rename(newNick);
				_userList.invalidate();
				return true;
			}
			return false;
		}
		
		private function getUserIndex(nick:String):int
		{
			var i:int = 0;
			var user:User;
			for(i=0; i< this._userList.dataProvider.length; i++)
			{
				user = _userList.dataProvider.getItemAt(i) as User;
				if(user.equals(nick))
					return i;
			}
			return -1;
		}
		
		private function sortUserList():void
		{
			this._userList.dataProvider.data.sortOn(["prefix", "nick"], [Array.DESCENDING, Array.CASEINSENSITIVE]);
			this._userList.dataProvider.setItems(this._userList.dataProvider.data, true);
		}
		
		private function onSend(event:MouseEvent):void
		{
			sendInputMsg();
		}
		
		private function keyPressed(e:KeyboardEvent):void{
			if(e.keyCode == Keyboard.ENTER){
				sendInputMsg();
			}
		}
		private function sendInputMsg():void
		{
			if(_inputTI.text.length == 0){
				return;
			}
			
			if(!_flexIrcClient.isConnected())
			{
				return;
			}
			
			if(_inputTI.text.charAt(0) == '/'){
				_flexIrcClient.sendRawLine(_inputTI.text.substr(1)+"\n");
				appendHTML(_inputTI.text + "<br>");
			}else{
				_flexIrcClient.sendMessage(_channel, _inputTI.text+"\n");
				appendHTML(flexIrcClient.getNick() + ">" + _inputTI.text + "<br>");
			}
			_inputTI.text = "";
		}
		
		private function onUserListClick(event:ListEvent):void
		{
			var user:User = event.data as User;
			_targetLbl.text = user.nick;
			_actionDP.enabled = true;

		}
		
		private function deactivateChannel():void
		{
			//this.channel = this.channel + "(inactive)";
			//this.status = "Inactive";
		}
		/**
		 * The IRC channel this ChannelWindow represents 
		 */
		public function get channel():String
		{
			return this._channel;   
		}
		public  function set channel(value:String):void
		{
			this._channel = value;
		}
		
		/**
		 * Public getter and setter for the IRC Client Connection Object
		 */
		public function get flexIrcClient():FlexIrcClient
		{
			return _flexIrcClient;  
		}
		public function set flexIrcClient(value:FlexIrcClient):void
		{
			_flexIrcClient = value;
		}
		
		/* START OF IRC Event Handlers */
		protected function onInvite(event:ChannelEvent):void      
		{
			if (!channelCheck(event.channel)){return;}
			/*
			event.targetNick
			event.sender
			event.login
			event.hostname
			event.channel
			*/
		}
		
		
		protected function onUserList(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			var users:Array = event.users;
			this._userList.dataProvider = new DataProvider(users);
			this.sortUserList();
		}
		
		protected function onMessage( event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			if(event.message.indexOf(_flexIrcClient.getNick()) != -1)
				this.appendHTML("<span class='msg2me'>" + event.sender + "</span>> " + event.message + "<br>");
			else
				this.appendHTML(event.sender + "> " + event.message + "<br>");
		}
		
		protected function onJoin(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			addNewUserToGui(event.sender);
			this.appendHTML("<span class='channelMsg'>--&gt;User Joined: " + event.sender + "(" + event.login + ")</span>" + "<br>");
		}
		
		protected function onPart(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>&lt;-- User Left: " + event.sender + "(" + event.login + ")</span>" + "<br>");
			removeUserFromGui(event.sender);
			if(_targetLbl.text == event.sender)
			{
				_targetLbl.text = '';
				_actionDP.enabled = false;
			}
			// TODO
			if (event.sender == this.flexIrcClient.getNick())
				deactivateChannel();
		}
		
		protected function onKick(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}		
			
			if (event.targetNick == this.flexIrcClient.getNick()){
				_userList.dataProvider.removeAll();
				this.appendHTML("<span class='channelMsg'>You " + event.targetNick+ " were kicked by " + event.sender + " (" + event.message + ")</span>" + "<br>");
			}
			else {
				this.appendHTML("<span class='channelMsg'>User: " + event.targetNick+ " was kicked by " + event.sender + " (" + event.message + ")</span>" + "<br>");
				removeUserFromGui(event.targetNick);
			}
		}
		
		protected function onTopic(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			if (event.changed)
			{
				if (event.sender != null)
					this.appendHTML("<span class='channelMsg'>User: " + event.sender + " sets topic to: " + event.message + "</span><br>");
				else
					this.appendHTML("<span class='channelMsg'>Topic: " + event.message + "</span><br>");
				//this.title = this.channel + " - " + event.message.substr(0,50);
			} else {
				if (event.sender == null)
					this.appendHTML("<span class='channelMsg'>*** Topic: " + event.message + "</span><br>");
				else
				{
					var date:Date = new Date();
					date.setMilliseconds(event.date);
					this.appendHTML("<span class='channelMsg'>*** Topic was set by " + event.sender + " on " + date + ".</span><br>");
				}
			}
		}
		
		protected function onChannelInfo( event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>Channel: " + event.channel + " (" + event.userCount + ") Topic: " + event.message + "</span><br>");
		}
		
		protected function onMode(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " Changes channel mode to: " + event.mode + "<br>");
		}
		
		protected function onOp(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			var index:int = this.getUserIndex(event.targetNick);
			if(index != -1)
			{
				var user:User = _userList.dataProvider.getItemAt(index) as User;
				if(user.hasVoice())
					user.prefix = "@+";
				else 
					user.prefix = "@";
				_userList.invalidate();
			}
			this.appendHTML("<span class='channelMsg'>User: " + event.targetNick + " received Op status (conferred by: " + event.sender + ")</span>" + "<br>");
		}
		
		protected function onDeop(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			var index:int = this.getUserIndex(event.targetNick);
			if(index != -1)
			{
				var user:User = _userList.dataProvider.getItemAt(index) as User;
				if(user.hasVoice())
					user.prefix = "+";
				else 
					user.prefix = "";
				_userList.invalidate();
			}
			this.appendHTML("<span class='channelMsg'>User: " + event.targetNick + " sees Op status revoked (by: " + event.sender + ")</span>" + "<br>");
		}
		
		protected function onVoice(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			var index:int = this.getUserIndex(event.targetNick);
			if(index != -1)
			{
				var user:User = _userList.dataProvider.getItemAt(index) as User;
				if(user.isOp())
					user.prefix = "@+";
				else 
					user.prefix = "+";
				_userList.invalidate();
			}
			this.appendHTML("<span class='channelMsg'>User: " + event.targetNick + " is given a voice (by: " + event.sender + ")</span>" + "<br>");
		}
		
		protected function onDeVoice(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			var index:int = this.getUserIndex(event.targetNick);
			if(index != -1)
			{
				var user:User = _userList.dataProvider.getItemAt(index) as User;
				if(user.isOp())
					user.prefix = "@";
				else 
					user.prefix = "";
				_userList.invalidate();
			}
			this.appendHTML("<span class='channelMsg'>User: " + event.targetNick + " sees his voice muted (by: " + event.sender + ")</span>" + "<br>");
		}
		
		protected function onSetChannelKey(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " sets channel key: " + event.message + "</span><br>");
		}
		
		protected function onRemoveChannelKey(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " removes channel key: " + event.message + "</span><br>" );
		}
		
		protected function onSetChannelLimit(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " sets channel limit: " + event.limit + "</span><br>" );
			
		}
		
		protected function onRemoveChannelLimit(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " removes channel limit" + "</span><br>" );
		}
		
		protected function onSetChannelBan(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " sets channel ban for hostmask: " + event.hostmask + "</span><br>");
			
		}
		
		protected function onRemoveChannelBan(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " removes channel ban for hostmask: " + event.hostmask + "</span><br>");
			
		}
		
		protected function onSetTopicProtection(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " turns topic protection on" + "</span><br>");
			
		}
		
		protected function onRemoveTopicProtection(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " removes topic protection" + "</span><br>");
			
		}
		
		protected function onSetNoExternalMessages(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			var log:String = ("<span class='channelMsg'>User: " as String);
			log = log  +  (event.sender as String);
			log = log  + (" turns external messages off" as String);
			this.appendHTML(log + "</span><br>");
			
		}
		
		protected function onRemoveNoExternalMessages(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " allows external messages" + "</span><br>");
		}
		
		protected function onSetInviteOnly(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " sets channel to invite only" + "</span><br>");
			
		}
		
		protected    function onRemoveInviteOnly(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " removes invite only from channel" + "</span><br>");
			
		}
		
		protected function onSetModerated(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " sets channel to moderated" + "</span><br>");
		}
		
		protected function onRemoveModerated(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " removes channel  moderation" + "</span><br>");
		}
		
		protected function onSetPrivate(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " sets channel to private" + "</span><br>");
		}
		
		protected function onRemovePrivate(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " removes channel's private setting" + "</span><br>");
			
		}
		
		protected function onSetSecret(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " makes channel secret" + "</span><br>");
			
		}
		
		protected function onRemoveSecret(event:ChannelEvent):void 
		{
			if (!channelCheck(event.channel)){return;}
			this.appendHTML("<span class='channelMsg'>User: " + event.sender + " removes channel's secret setting" + "</span><br>");
			
		}
		
		protected function onDisconnect(event:ServerEvent):void
		{
			this._userList.removeAll();
			_targetLbl.text = '';
			_actionDP.enabled = false;
			this.appendHTML("<span class='serverMsg'>Disconnected.</span><br>");
		}
		
		protected function onNickChange(event:UserEvent):void
		{
			if(renameUserFromGui(event.sender, event.newNick))
			{
				if(_targetLbl.text == event.sender)
					_targetLbl.text = event.newNick;
				this.appendHTML("<span class='channelMsg'>* " + event.sender + " is known as " + event.newNick + "</span><br>");
		
			}
		}
		
		protected function onQuit(event:UserEvent):void
		{
			if(removeUserFromGui(event.sender))
			{
				if(_targetLbl.text == event.sender)
				{
					_targetLbl.text = '';
					_actionDP.enabled = false;
				}
				
				this.appendHTML("<span class='serverMsg'>* " + event.sender + "(" + event.login + "@" + event.hostname + ") Quit (" + event.message + ")</span><br>");
			}
		}
		
		protected function onConnect(event:ServerEvent):void
		{
			_flexIrcClient.sendRawLine("join " + _channel);
			this.appendHTML("<span class='channelMsg'>* Rejoining the channel...</span><br>");
		}
		
		/* END OF IRC Event Handlers */
		public function appendHTML(html:String):void
		{
			_statusText.htmlText += html;
			if(_statusText.textHeight > _txtScrlr.height){
				_txtScrlr.scrollY = _statusText.textHeight;
				_txtScrlr.update();
				//setTimeout(_txtScrlr.update(), 100);
			}
			
		}
		
		protected function onUserAction(event:Event):void
		{
			if(!_flexIrcClient.isConnected())
				return;
			if(event.target.selectedIndex == 0)
			{
				var evt:UIEvent = new UIEvent(UIEvent.OPEN_PRIVATE_CHAT);
				evt.channel = _targetLbl.text;
				Events.SharedData.instance.dispatchEvent(evt);
			}
		}
		
		protected function onTargetLblClick(event:MouseEvent):void
		{
			_inputTI.text += _targetLbl.text + ':';
		}
	}
}